﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NFit.Core;
using NFit.Core.Config;
using NFit.Core.Interfaces;
using NFit.Core.Reports;
using System.IO;
using log4net;
using System.Configuration;
using System.Reflection;
using System.Security.Policy;

namespace NFit.Console
{
    class ConsoleRunner
    {
        static ILog logger;
        private string[] arguments;
        private bool _helpmode = false;

        private string lookupDirectory;
        private string configFile;

        public bool HelpMode
        {
            get
            {
                return _helpmode;
            }
        }

        public ConsoleRunner(string[] args)
        {
            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
            arguments = args;

            _helpmode = Help(ArgumentValue("help"));

            if (!HelpMode)
            {
                Configure(ArgumentValue("config"));
            }
        }

        Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            string assPath = Path.Combine(Path.GetDirectoryName(configFile), args.Name + ".dll");
            System.Console.WriteLine("Trying to load external assembly from " + assPath);
            logger.Debug("trying to load external assembly from " + assPath);
            Assembly myAssembly = Assembly.LoadFrom(assPath);
            return myAssembly;
        }

        private bool Help(string argkey)
        {
            if (argkey == null)
                return false;

            // TODO write console help here

            return true;
        }

        private string ArgumentValue(string argkey)
        {
            foreach(string arg in arguments)
            {
                if (arg == "-"+argkey)
                    return string.Empty;

                if (arg.StartsWith("-"+argkey + "="))
                {
                    int idx = arg.IndexOf("=");
                    string argValue = arg.Substring(idx + 1);
                    if (argValue.StartsWith("\"") && argValue.EndsWith("\""))
                    {
                        argValue = argValue.Substring(1, argValue.Length - 2);
                    }

                    return argValue;
                }
            }

            return null;
        }

        private void Configure(string configFile)
        {
            log4net.Config.XmlConfigurator.Configure();
            logger = log4net.LogManager.GetLogger(typeof(ConsoleRunner));
            if (!string.IsNullOrEmpty(configFile))
            {
                this.configFile = configFile;
            }
        }

        private BaseRunner GetRunner()
        {
            BaseRunner runner = new BaseRunner();
            if (!string.IsNullOrEmpty(configFile))
            {                
                runner.Config.ReadConfig(configFile);  
            }
            else
            {
                runner.Config.ReadAppConfig();
            }
            
            return runner;            
        }

        public void Run()
        {            
            if (!_helpmode)
            {
                BaseRunner runner = GetRunner();
                
                if (runner.Config.Writers.Count == 0)
                    runner.Config.Writers.Add(new ConsoleReport());

                runner.Run();
            }
        }
    }
}
